package com.woniuxy.certified.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.*;
import com.woniuxy.certified.dao.CertifiedAccount;
import com.woniuxy.certified.dao.CertifiedInfo;
import com.woniuxy.certified.mapper.CertifiedAccountMapper;
import com.woniuxy.certified.mapper.CertifiedInfoMapper;
import com.woniuxy.certified.model.dto.CertifiedInfoDto;
import com.woniuxy.certified.model.param.LoadAllCertifiedParam;
import com.woniuxy.certified.model.param.LoadAllcertifiedinfoParam;
import com.woniuxy.certified.model.param.UpdateChargePriceParam;
import com.woniuxy.certified.model.param.UpdateStallPriceParam;
import com.woniuxy.certified.service.CertifiedInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.core.exception.accountException.AccountException;
import com.woniuxy.core.exception.accountException.AccountExceptionCode;
import com.woniuxy.core.exception.certifiedException.CertifiedException;
import com.woniuxy.core.exception.certifiedException.CertifiedExceptionCode;
import com.woniuxy.core.util.PageInfo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 凌玉春
 * @since 2024年01月15日
 */
@Service
public class CertifiedInfoServiceImpl extends ServiceImpl<CertifiedInfoMapper, CertifiedInfo> implements CertifiedInfoService {

    @Resource
    private CertifiedInfoMapper certifiedInfoMapper;

    @Resource
    private CertifiedAccountMapper accountMapper;

    @Override
    public PageInfo<CertifiedInfoDto> loadAllCertified(LoadAllCertifiedParam param) {
        Page<CertifiedInfo> page = new Page<CertifiedInfo>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 5 : param.getPageSize());
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<CertifiedInfo>();
        //物业名称模糊查询
        if(param.getCertifiedInfoName()!=null){
            wrapper.like(true,"certified_info_name",param.getCertifiedInfoName());
        }
        //经纬度距离查询
        if(param.getCertifiedInfoLongitude()!=null&&param.getCertifiedInfoLatitude()!=null){
            QueryWrapper<CertifiedInfo> wrapper1 = new QueryWrapper<CertifiedInfo>();
            wrapper1.orderByDesc("certified_info_id");
            List<CertifiedInfo> certifiedInfos = certifiedInfoMapper.selectList(wrapper1);
            HashMap<Object, Object> map = new HashMap<Object, Object>();
            for (CertifiedInfo certifiedInfo : certifiedInfos) {
                CertifiedInfoDto dto = BeanUtil.toBean(certifiedInfo, CertifiedInfoDto.class);

            }
        }
        certifiedInfoMapper.selectPage(page,wrapper);
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setList(page.getRecords());
        pageInfo.setPages(page.getPages());
        System.out.println(pageInfo);
        return pageInfo;
    }

    @Override
    public CertifiedAccount findCertifiedAccountById(Integer certifiedInfoId) {
        CertifiedAccount certifiedAccount = accountMapper.selectById(certifiedInfoId);
        if (certifiedAccount==null) throw new CertifiedException(CertifiedExceptionCode.ACCOUNT_INEXISTENCE);
        return certifiedAccount;
    }

    @Override
    public void updateStallPrice(UpdateStallPriceParam param) {
        //是否存在该物业
        CertifiedInfo certifiedInfo = certifiedInfoMapper.selectById(param.getCertifiedInfoId());
        if(certifiedInfo==null){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_NOT_EXIST);
        }
        //修改价格
        certifiedInfo.setStallUnitPrice(BigDecimal.valueOf(param.getPrice()));
        certifiedInfoMapper.updateById(certifiedInfo);
    }

    @Override
    public void updateChargePrice(UpdateChargePriceParam param) {
        //是否存在该物业
        CertifiedInfo certifiedInfo = certifiedInfoMapper.selectById(param.getCertifiedInfoId());
        if(certifiedInfo==null){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_NOT_EXIST);
        }
        //修改价格
        certifiedInfo.setChargeUnitPrice(BigDecimal.valueOf(param.getPrice()));
        certifiedInfoMapper.updateById(certifiedInfo);
    }

    @Override
    public CertifiedInfo findCertifiedById(Integer certifiedInfo) {
        System.out.println(certifiedInfo);
        CertifiedInfo certifiedInfo1 = certifiedInfoMapper.selectById(certifiedInfo);
        if (certifiedInfo1==null) throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_NOT_EXIST);
        return certifiedInfo1;
    }

    @Override
    public PageInfo<CertifiedInfo> loadAllcertifiedinfo(LoadAllcertifiedinfoParam param) {
        Page<CertifiedInfo> page = new Page<CertifiedInfo>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 5 : param.getPageSize());
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<CertifiedInfo>();
        certifiedInfoMapper.selectPage(page,wrapper);
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setList(page.getRecords());
        pageInfo.setPages(page.getPages());
        System.out.println(pageInfo);
        return pageInfo;
    }


    public static double distance(Double a,Double b,Double c,Double d) {
        // 当前位置的经纬度坐标
        double currentLat = Math.toRadians(a); // 当前位置的纬度
        double currentLng = Math.toRadians(b); // 当前位置的经度

        // 目标位置的经纬度坐标
        double targetLat = Math.toRadians(c); // 目标位置的纬度
        double targetLng = Math.toRadians(d); // 目标位置的经度

        double distance = calculateDistance(currentLat, currentLng, targetLat, targetLng);
        System.out.println("与当前位置的距离：" + distance + " 公里");
        return distance;
    }

    public static double calculateDistance(double lat1, double lng1, double lat2, double lng2) {
        // 地球半径，单位为公里
        double EARTH_RADIUS = 6371;
        double dLat = lat2 - lat1;
        double dLng = lng2 - lng1;
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(lat1) * Math.cos(lat2) *
                        Math.sin(dLng / 2) * Math.sin(dLng / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return EARTH_RADIUS * c;
    }


    public static void main(String[] args) throws IOException, GeoIp2Exception {
        String destFilePath = new File("GeoLite2-City.mmdb").getAbsolutePath();
        File database = new File(destFilePath);

        // 读取数据库内容
        DatabaseReader reader = new DatabaseReader.Builder(database).build();
        InetAddress ipAddress = InetAddress.getByName("221.178.32.228");//要解析的ip地址

        // 获取查询结果
        CityResponse response = reader.city(ipAddress);

        // 获取国家信息
        Country country = response.getCountry();
        System.out.println(country.getIsoCode());               // 'CN'
        System.out.println(country.getName());                  // 'China'
        System.out.println(country.getNames().get("zh-CN"));    // '中国'

        // 获取省份
        Subdivision subdivision = response.getMostSpecificSubdivision();
        System.out.println(subdivision.getName());   // 'Guangxi'
        System.out.println(subdivision.getIsoCode()); // 'GX'
        System.out.println(subdivision.getNames().get("zh-CN")); // '广西壮族自治区'

        // 获取城市
        City city = response.getCity();
        System.out.println(city.getName()); // 'Guilin'
        Postal postal = response.getPostal();
        System.out.println(postal.getCode()); // 'null'
        System.out.println(city.getNames().get("zh-CN")); // '桂林市'
        Location location = response.getLocation();
        System.out.println(location.getLatitude());  // 25.2802
        System.out.println(location.getLongitude()); // 110.2964
    }


}
